package Set;


import java.util.*;

/**
 * ArrayList
 * LinkedList
 */
public class TestList {
    public static void main(String[] args) {
        travelList();
        listToArray();

        test();
        testShuffle();
        testEquals();
    }

    private static void travelList() {
        List<String> list = List.of("apple", "pear", "banana");
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            System.out.println(s);
        }

        System.out.println("--------------------------------------------");

        for (Iterator<String> itr = list.iterator(); itr.hasNext(); ) {
            String s = itr.next();
            System.out.println(s);
        }

        System.out.println("--------------------------------------------");
        for (String s : list) {
            System.out.println(s);
        }

        System.out.println("--------------------------------------------");
    }

    private static void listToArray() {
        List<Integer> list = List.of(1, 22, 33);
        Object[] array1 = list.toArray();
//        list.toArray(new Integer[list.size()]);
        for (Object b : array1) {
            System.out.println(b);
        }

        System.out.println("--------------------------------------------");

        Number[] array2 = list.toArray(new Integer[list.size()]);
        for (Number integer : array2) {
            System.out.println(integer);
        }

        System.out.println("--------------------------------------------");

        // below jdk 11
        List<Number> listNum = Arrays.asList(array2);
        for (Number num : listNum) {
            System.out.println(num);
        }

        System.out.println("--------------------------------------------");
    }

    private static void test() {
        // 构造从start到end的序列：
        final int start = 10;
        final int end = 20;
        List<Integer> list = new ArrayList<>();
        for (int i = start; i <= end; i++) {
            list.add(i);
        }
        // 随机删除List中的一个元素:
        int removed = list.remove((int) (Math.random() * list.size()));
        int found = findMissingNumber(start, end, list);
        System.out.println("remove: " + removed);
        System.out.println(list.toString());
        System.out.println("found missing number: " + found);
        System.out.println(removed == found ? "测试成功" : "测试失败");

        System.out.println("--------------------------------------------");
    }

    private static int findMissingNumber(int start, int end, List<Integer> list) {
        int count = 0;
        for (int i = start; i <= end; i++) {
            if (list.contains(i)) {
                count++;
            } else {
                break;
            }
        }
        return count + start;
    }

    private static  void testShuffle() {
        // 构造从start到end的序列：
        final int start = 10;
        final int end = 20;
        List<Integer> list = new ArrayList<>();
        for (int i = start; i <= end; i++) {
            list.add(i);
        }
        // 洗牌算法shuffle可以随机交换List中的元素位置:
        Collections.shuffle(list);
        // 随机删除List中的一个元素:
        int removed = list.remove((int) (Math.random() * list.size()));
        int found = findMissingNumber(start, end, list);

        System.out.println("remove: " + removed);
        System.out.println(list.toString());
        System.out.println("missing number: " + found);
        System.out.println(removed == found ? "测试成功" : "测试失败");

        System.out.println("--------------------------------------------");
    }

    private static void testEquals() {
        List<String> list = List.of("A", "B", "C");
        System.out.println(list.contains("C")); // true
        System.out.println(list.contains("X")); // false
        System.out.println(list.indexOf("C")); // 2
        System.out.println(list.indexOf("X")); // -1

        System.out.println(list.contains(new String("C"))); // true or false?
        System.out.println(list.indexOf(new String("C"))); // 2 or -1?

        System.out.println("--------------------------------------------");


        List<Person> listPerson = List.of(
                new Person("Li lei"),
                new Person("Han mei mei"),
                new Person("Bob"),
                new Student("Make")
        );

        System.out.println(listPerson.contains(new Person("Bob")));
        System.out.println(listPerson.contains(new Student("Make")));
        System.out.println(listPerson.contains(new Person("Make")));

        System.out.println("--------------------------------------------");


        List<Person2> list2 = List.of(
                new Person2("Xiao", "Ming", 18),
                new Person2("Xiao", "Hong", 25),
                new Person2("Bob", "Smith", 20)
        );
        boolean exist = list2.contains(new Person2("Bob", "Smith", 20));
        System.out.println(exist ? "测试成功!" : "测试失败!");

        System.out.println("--------------------------------------------");
    }

    private static class Student extends Person {
        public Student(String name) {
            super(name);
        }
    }
    private static class Person {
        String name;
        public Person(String name) {
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return Objects.equals(name, person.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    }

    private static class Person2 {
        String firstName;
        String lastName;
        int age;
        public Person2(String firstName, String lastName, int age) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age = age;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person2 person2 = (Person2) o;
            return age == person2.age && Objects.equals(firstName, person2.firstName) && Objects.equals(lastName, person2.lastName);
        }

        @Override
        public int hashCode() {
            return Objects.hash(firstName, lastName, age);
        }
    }
}
